package com.example.graduationdesign.service.Impl;

import com.example.graduationdesign.constant.Constant;
import com.example.graduationdesign.exception.CustomizeException;
import com.example.graduationdesign.mapper.AdminMapper;
import com.example.graduationdesign.mapper.CommonMapper;
import com.example.graduationdesign.pojo.dao.ArticleDao;
import com.example.graduationdesign.pojo.dao.UserDao;
import com.example.graduationdesign.pojo.dao.WordDao;
import com.example.graduationdesign.pojo.dto.*;
import com.example.graduationdesign.pojo.vo.EmailReceiver;
import com.example.graduationdesign.pojo.vo.PageInfo;
import com.example.graduationdesign.pojo.vo.ResultCode;
import com.example.graduationdesign.pojo.vo.UserVo;
import com.example.graduationdesign.service.AdminService;
import com.example.graduationdesign.utils.CommonUtil;
import com.example.graduationdesign.utils.EmailUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class AdminServiceImpl implements AdminService {

    @Value("${spring.mail.username}")
    private String sender;

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private CommonMapper commonMapper;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 用于实现用户的分页功能
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<UserDao> SelectUser(Integer pageNo, Integer pageSize) {
        List<UserDao> list = adminMapper.SelectUserInfo((pageNo - 1) * pageSize, pageSize);
        return new PageInfo<>(adminMapper.GetUserCount(), list);
    }

    /**
     * 用于实现对文章的管理
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<ArticleDao> SelectArticle(Integer pageNo, Integer pageSize) {
        List<ArticleDao> list = adminMapper.SelectArticleInfo((pageNo - 1) * pageSize, pageSize);
        return new PageInfo<>(adminMapper.GetArticleCount(),list);
    }

    /**
     * 用于对用户查看的分页功能
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<WordDao> SelectWord(Integer pageNo, Integer pageSize) {
        List<WordDao> list = adminMapper.SelectWordInfo((pageNo - 1) * pageSize, pageSize);
        return new PageInfo<>(adminMapper.GetWordCount(), list);
    }


    /**
     * 获取活跃用户的数量
     * @return
     */
    @Override
    public Integer GetLiveStudent() {
        Integer liveStudentNumber = adminMapper.GetStudentCount();
        return liveStudentNumber;
    }

    /**
     * 用于管理员获取已打卡用户的人数
     * @return
     */
    @Override
    public Integer GetCheckCount() {
        Integer CheckCount = adminMapper.GetCheckCount();
        return CheckCount;
    }

    /**
     * 查询文章内容
     * @param articleId
     * @return
     */
    @Override
    public List<ArticleDao> SearchArticle(Long articleId) {
        List<ArticleDao> articleDao = adminMapper.SearchArticle(articleId);
        return articleDao;
    }

    /**
     * 新增文章的内容
     * @param author
     * @param content
     * @param image
     * @param title
     * @return
     */
    @Override
    public Void InsertArticle(String author, String content, String image, String title) {
        adminMapper.InsertArticle(title,content,author,image);
        return null;
    }

    /**
     * 用于有图像修改的编辑中
     * @param code
     * @param author
     * @param content
     * @param image
     * @param title
     * @return
     */
    @Override
    public Void UpdateArticle1(Long code, String author, String content, String image, String title) {
        adminMapper.UpdateArticleOne(title,content,author,image,code);
        return null;
    }


    public Void UpdateArticle2(Long code, String author, String content, String title) {
        adminMapper.UpdateArticleTwo(title,content,author,code);
        return null;
    }

    /**
     * 用于实现删除文章的操作
     * @param code
     * @return
     */
    @Override
    public Void DeleteArticle(Long code) {
        adminMapper.DeleteArticle(code);
        return null;
    }


    /**
     * 用于获取用户的排名信息
     * @param stage
     * @return
     */
    @Override
    public List<RankDto> GetStudentRanking(Integer stage) {
        List<RankDto> rankDtos = adminMapper.GetStudentRanking(stage);
        return rankDtos;
    }

    /**
     * 用于管理员修改用户的基本信息
     * @param userId
     * @param sex
     * @param age
     * @param userName
     * @param phone
     * @param email
     * @return
     */
    @Override
    public Void UpdateUserInfo(Long userId, Integer sex, Integer age, String userName, String phone, String email) {
        adminMapper.UpdateUserInfo(userId, sex, age, userName,  phone,  email);
        return null;
    }

    /**
     * 用于管理员逻辑删除用户的基本信息
     * @param userId
     * @param isActive
     * @return
     */
    @Override
    public Void DeleteUserInfo(Long userId, Integer isActive) {
        adminMapper.DeleteUserInfo(userId,isActive);
        return null;
    }

    /**
     * 用于管理员查询用户的基本信息
     * @param userId
     * @param userName
     * @return
     */
    @Override
    public List<UserDao> SearchUserInfo(Long userId, String userName) {
        List<UserDao> userDaos = adminMapper.SearchUserInfo(userId,userName);
        return userDaos;
    }


    /**
     * 用于实现管理员更新单词信息的功能
     * @param wordDao
     * @return
     */
    @Override
    public Void UpdateWordInfo(WordDao wordDao) {
        adminMapper.UpdateWordInfo(wordDao);
        return null;
    }


    /**
     * 用于实现管理员添加单词的功能
     * @param wordDao
     * @return
     */
    @Override
    public Void AddWordInfo(WordDao wordDao) {
        adminMapper.AddWordInfo(wordDao);
        return null;
    }

    /**
     * 按照单词查询
     * @param searchInput
     * @return
     */
    @Override
    public List<WordDao> SearchWordInfoByName(String searchInput) {
        List<WordDao> wordDaos = adminMapper.SearchWordInfoByName(searchInput);
        return wordDaos;
    }

    /**
     * 按照单词所属阶段查询
     * @param searchInput
     * @return
     */
    @Override
    public List<WordDao> SearchWordInfoByStage(String searchInput) {
        List<WordDao> wordDaos = adminMapper.SearchWordInfoByStage(searchInput);
        return wordDaos;
    }

    /**
     * 按照单词难度查询
     * @param searchInput
     * @return
     */
    @Override
    public List<WordDao> SearchWordInfoByDifficulty(String searchInput) {
        List<WordDao> wordDaos = adminMapper.SearchWordInfoByDifficulty(searchInput);
        return wordDaos;
    }

    /**
     * 获取用户的行为数据
     * @param startDate
     * @param endDate
     * @return
     */

    @Override
    public DataAnalysisDto GetDataAnalysis(String startDate, String endDate) {
        List<BarChartDto> barChartDtos = adminMapper.GetBarChartData(startDate,endDate);
        List<LineChartDto> lineChartDtos = adminMapper.GetLineChartData(startDate,endDate);
        List<PieChartDto> pieChartDtos = adminMapper.GetUserVarietyData();
        RadarChartDto radarChartDto = adminMapper.GetUserAction(startDate,endDate);
        DataAnalysisDto dataAnalysisDto = new DataAnalysisDto();
        dataAnalysisDto.setBarChartData(barChartDtos);
        dataAnalysisDto.setLineChartData(lineChartDtos);
        dataAnalysisDto.setPieChartData(pieChartDtos);
        dataAnalysisDto.setRadarChartData(radarChartDto);
        return dataAnalysisDto;
    }


    /**
     * 用于实现获取某个地区用户人数
     * @return
     */
    @Override
    public List<CityDto> GetCity(){
        List<CityDto> cityDtos = adminMapper.GetCity();

        return cityDtos;
    }

    /**
     * 将前端文件中的数据取出来之后放在数据库中的实现层
     * @param wordDaos
     * @return
     */
    @Override
    public Integer SetData(List<WordDao> wordDaos) {
        int flag = 0;
        for(WordDao wordDao:wordDaos){
            if(adminMapper.IsExistWord(wordDao.getWord()) == 0){
                adminMapper.AddWordInfo(wordDao);
                flag++;
            }
        }
        return flag;
    }


    /**
     * 用于实现管理员获取验证码的功能
     * @param email
     * @param newEmail
     * @return
     */
    @SneakyThrows
    @Override
    public String sendModifyAdminEmail(String email,String newEmail) {
        // 0. 判断该邮箱是否在数据库存在
        Long userId = commonMapper.getUserIdByEmail(email);
        if (!Optional.ofNullable(userId).isPresent()) {
            throw new CustomizeException(ResultCode.USER_EMAIL_NOT_EXIST);
        }

        // 1. 生成验证码
        String verificationCode = CommonUtil.generateVerificationCode(6);
        System.out.println(verificationCode);

        // 2. 给目标用户发送邮件
        // 2.1. 创建MINE邮件信息
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
        // 2.2. 完善邮件信息
        // 2.2.1. 编辑邮件
        EmailReceiver emailReceiver = new EmailReceiver();
        emailReceiver.setSubject("邮箱修改");
        EmailReceiver.Content content = emailReceiver.new Content();
        content.setExpirationTime(Constant.VERIFICATION_CODE_EXIST_TIME);
        content.setTitle("邮箱修改");
        content.setText("您的验证码");
        content.setCode(verificationCode);
        emailReceiver.setContent(content);
        // 2.2.2. 发送者
        mineHelper.setFrom(sender);
        // 2.2.3. 接收方
        mineHelper.setTo(newEmail);
        // 2.2.4. 邮件标题
        mineHelper.setSubject(emailReceiver.getSubject());
        // 2.2.5. 邮件内容 true  表示邮件内容带有附件或html
        mineHelper.setText(EmailUtil.verificationCodeEmailFormatModifyEmail(emailReceiver), true);
        // 2.3. 发送邮件
        mailSender.send(message);

        // 3. 在Redis存储验证码，为了修改密码时验证用户发送的验证码是否合法
        // 3.1. 获取用户 token
        String token = CommonUtil.getCurrentUserToken();
        // 3.2. 存储数据
        redisTemplate.opsForValue().set(Constant.EMAIL_VERIFY + token, verificationCode, Constant.VERIFICATION_CODE_EXIST_TIME, TimeUnit.MINUTES);

        System.out.println("-------------------------------------------------");
        System.out.println(token);
        System.out.println("-------------------------------------------------");
        // 4. 返回验证码
        return verificationCode;
    }


    /**
     * 用于修改管理员邮箱
     * @param modifyAdminEmailDto
     * @return
     */
    @Override
    public Void updateAdminEmailInformation(ModifyAdminEmailDto modifyAdminEmailDto) {
        System.out.println(modifyAdminEmailDto);
        // 2. 在Redis中取出验证码，和发送请求验证码比对
        // 2.1. 获取 token
        String token = CommonUtil.getCurrentUserToken();

        // 2.2. 获取 Redis 里面的目标验证码
        String verificationCode = (String) redisTemplate.opsForValue().get(Constant.EMAIL_VERIFY + token);
        System.out.println(verificationCode);
        if (!Optional.ofNullable(verificationCode).isPresent()) {
            throw new CustomizeException(ResultCode.VERIFICATION_CODE);
        }
        // 2.3. 比较验证码
        if (!verificationCode.equals(modifyAdminEmailDto.getVerificationCode())) {
            throw new CustomizeException(ResultCode.VERIFICATION_CODE);
        }
        adminMapper.updateAdminEmailInformation(modifyAdminEmailDto);
        return null;
    }


}
